#ifndef SEMANTICHIGHLIGHTER_H
#define SEMANTICHIGHLIGHTER_H

#include "semanticinfo.h"

#include <QFutureWatcher>
#include <QTextLayout>
#include <QVector>

class JSEditor;

class HighlightingResult {
public:
    unsigned line; // 1-based
    unsigned column; // 1-based
    unsigned length;
    int kind;

    bool isValid() const
    { return line != 0; }

    bool isInvalid() const
    { return line == 0; }

    HighlightingResult()
        : line(0), column(0), length(0), kind(0)
    {}

    HighlightingResult(unsigned line, unsigned column, unsigned length, int kind)
        : line(line), column(column), length(length), kind(kind)
    {}

    bool operator==(const HighlightingResult& other) const
    {
        return line == other.line
                && column == other.column
                && length == other.length
                && kind == other.kind;
    }
};

class SemanticHighlighter : public QObject
{
    Q_OBJECT
public:
    enum UseType
    {
        UnknownType,
        LocalIdType, // ids in the same file
        ExternalIdType, // ids from instantiating files
        QmlTypeType, // qml types
        RootObjectPropertyType, // property in root object
        ScopeObjectPropertyType, // property in scope object
        ExternalObjectPropertyType, // property in root object of instantiating file
        JsScopeType, // var or function in local js scope
        JsImportType, // name of js import
        JsGlobalType, // in global scope
        LocalStateNameType, // name of a state in the current file
        BindingNameType, // name on the left hand side of a binding
        FieldType, // member of an object
        Max // number of the last used value (to generate the warning formats)
    };

    explicit SemanticHighlighter(JSEditor *editor);


    void rerun(const SemanticInfo &scopeChain);
    void cancel();

    void reportMessagesInfo(const QVector<QTextLayout::FormatRange> &diagnosticRanges,
                                                 const QHash<int,QTextCharFormat> &formats);
    typedef HighlightingResult Use;
private slots:
    void applyResults(int from, int to);
    void finished();
private:
    QFutureWatcher<Use>  m_watcher;
    JSEditor            *m_editor;
    QHash<int, QTextCharFormat> m_formats;
    QHash<int, QTextCharFormat> m_extraFormats;
    QVector<QTextLayout::FormatRange> m_diagnosticRanges;
};

#endif // SEMANTICHIGHLIGHTER_H
